package com.emm.yixun.website.listeners;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import com.emm.yixun.common.model.enums.*;
import com.emm.yixun.customer.service.channel.ChannelSendHttpMessageService;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;
import org.apache.commons.lang3.StringUtils;

import com.emm.yixun.basic.service.CustomerService;
import com.emm.yixun.basic.service.HaveReceiveRefundService;
import com.emm.yixun.basic.service.NeedReceiveRefundService;
import com.emm.yixun.basic.service.PayDepositService;
import com.emm.yixun.basic.service.ProjectRoomService;
import com.emm.yixun.basic.service.RoomChangeHistoryService;
import com.emm.yixun.basic.service.SubscribeService;
import com.emm.yixun.common.model.HaveReceiveRefund;
import com.emm.yixun.common.model.PayDeposit;
import com.emm.yixun.common.model.Subscribe;
import com.emm.yixun.common.model.dto.HaveReceiveRefundDto;
import com.emm.yixun.common.model.dto.NeedReceiveRefundDto;
import com.emm.yixun.common.model.dto.NoticeEntity;
import com.emm.yixun.common.model.dto.PayDepositDto;
import com.emm.yixun.common.model.dto.ProjectRoomDto;
import com.emm.yixun.common.model.dto.RoomChangeHistoryDto;
import com.emm.yixun.common.model.dto.SubscribeDto;
import com.emm.yixun.customer.service.impl.app.ActivitiProcessServiceImpl;
import com.emm.yixun.customer.service.impl.app.SpringWebContextUtil;
import com.emm.yixun.system.service.notice.subscribe.SubscribeNoticeFacade;

public class SubscribeListeners implements Serializable, ExecutionListener{
	private static final long serialVersionUID = -4663488123522935330L;

	@Override
	public void notify(DelegateExecution execution) throws Exception {
		String id=execution.getProcessBusinessKey();
		String processInstanceId=execution.getProcessInstanceId();
		SubscribeService subscribeService=getSubscribeService();
		ProjectRoomService projectRoomService=getProjectRoomService();
		PayDepositService payDepositService=getPayDepositService();
		Subscribe subscribe=subscribeService.selectById(Long.valueOf(id));
		if(null==subscribe){
			throw new Exception("认购记录不存在");
		}
		if(getActivitiProcessServiceImpl().isCheckPass(processInstanceId)){
			/**
			 * 1.修改认购记录审核状态为通过   
			 * 2.记录房源变更记录
			 * 3.记录应收记录
			 * 4.更改客户交易状态为认筹，判断是否多套交易并更新状态
			 */
			//1.修改认筹记录审核状态为通过   
			SubscribeDto updateDto = new SubscribeDto();
			updateDto.setId(Long.valueOf(id));
			updateDto.setAuditStatus(AuditStatusEnum.SUCCESS.getNo());
			updateDto.setCheckDate(new Date());
			subscribeService.update(updateDto);
			if(subscribe.getPayDepositId()!=null){
				PayDepositDto payDepositDto = new PayDepositDto();
				payDepositDto.setBusinessStatus("2");
				payDepositDto.setId(subscribe.getPayDepositId());
				payDepositService.update(payDepositDto);
			}
			
			//2.记录房源变更记录
			RoomChangeHistoryDto dto=new RoomChangeHistoryDto();
			dto.setRoomId(subscribe.getRoomId());
			dto.setBusinessDynamics("认购");
			if(StringUtils.isBlank(subscribe.getPayDepositCode())){
				dto.setRemark("房源由【可售】转为【认购】");
			}else{
				dto.setRemark("房源由【小定】转为【认购】");
			}
			dto.setBusinessHref("/customer/subscribe/toView?id="+subscribe.getId()+"&returnUrl=,marketing,room,index");
    		dto.setMerchantId(subscribe.getMerchantId());
    		dto.setAccessCode(subscribe.getAccessCode());
    		dto.setCreateUserId(subscribe.getCreateUserId());
    		dto.setUserCode(subscribe.getUserCode());
    		dto.setDelFlag("0");
    		dto.setUpdateUserId(subscribe.getUpdateUserId());
    		dto.setUpdateTime(new Date());
    		RoomChangeHistoryDto rchSaveResponse=getRoomChangeHistoryService().create(dto);
    		if(rchSaveResponse == null){
    			throw new Exception("房源变更记录新增失败!");
    		}
			
			//3.记录应收记录
			NeedReceiveRefundDto needReceiveRefundDto=new NeedReceiveRefundDto();
			needReceiveRefundDto.setRelationId(subscribe.getId());
			needReceiveRefundDto.setBusinessType("1");
			needReceiveRefundDto.setTotalReceivablesAmount(subscribe.getDepositReceivable());
			needReceiveRefundDto.setCustomerId(subscribe.getCustomerId());
			needReceiveRefundDto.setRoomId(subscribe.getRoomId());
			needReceiveRefundDto.setStatus("1");
			needReceiveRefundDto.setPostponedStatus("0");
			needReceiveRefundDto.setDocType("0");
			needReceiveRefundDto.setRemark("认购收款");
			needReceiveRefundDto.setHousingFundType(HousingFundTypeEnum.FUNDTYPE_3.getNo());//认购金
			needReceiveRefundDto.setBusinessFlag(BusinessFlagEnum.BUSINESSFLAG_5.getNo());
			needReceiveRefundDto.setPostponedStatus("0");
			
			needReceiveRefundDto.setMerchantId(subscribe.getMerchantId());
			needReceiveRefundDto.setUserCode(subscribe.getUserCode());
			needReceiveRefundDto.setAccessCode(subscribe.getAccessCode());
			needReceiveRefundDto.setCreateUserId(subscribe.getCreateUserId());
			needReceiveRefundDto.setDelFlag("0");
			needReceiveRefundDto.setUpdateUserId(subscribe.getUpdateUserId());
			needReceiveRefundDto.setUpdateTime(new Date());
			NeedReceiveRefundDto nrrdSaveResponse=getNeedReceiveRefundService().create(needReceiveRefundDto);
			if(nrrdSaveResponse == null){
    			throw new Exception("待收/退款记录新增失败!");
    		}
			
			//认筹金转认购金
			if(subscribe.getPayDepositId()!=null){
				HaveReceiveRefundDto entity = new HaveReceiveRefundDto();
				entity.setRelationId(subscribe.getPayDepositId());
				entity.setDelFlag("0");
				entity.setDocType("0");
				List<HaveReceiveRefund> resList = getHaveReceiveRefundService().selectListByDto(entity);
				BigDecimal realAmount = new BigDecimal("0");
				if(resList != null){
					for(int i = 0; i < resList.size(); i++){
						HaveReceiveRefund have = (HaveReceiveRefund)resList.get(i);
						realAmount = realAmount.add(have.getRealAmount());
						HaveReceiveRefundDto haveDto = new HaveReceiveRefundDto();
						haveDto.setId(have.getId());
						haveDto.setBusinessFlag(BusinessFlagEnum.BUSINESSFLAG_3.getNo()); 
						haveDto.setDocType("1"); //已转出
						Integer resUpdate = getHaveReceiveRefundService().update(haveDto);
						if(resUpdate < 1){
			    			throw new Exception("认筹金转认购金（转出）更新失败！");
			    		}
					}
					HaveReceiveRefundDto haveReceiveRefundDto = new HaveReceiveRefundDto();
					haveReceiveRefundDto.setReceivablesId(nrrdSaveResponse.getId());
					haveReceiveRefundDto.setReceivablesType(BusinessTypeEnum.SUBSCRIBE.getNo());
					haveReceiveRefundDto.setRelationId(subscribe.getId());
					haveReceiveRefundDto.setRealAmount(realAmount);
					haveReceiveRefundDto.setDeductibleAmount(new BigDecimal("0"));
					haveReceiveRefundDto.setCustomerId(subscribe.getCustomerId());
					haveReceiveRefundDto.setRoomId(subscribe.getRoomId());
					haveReceiveRefundDto.setRemark("认筹金转认购金(转入)");
					haveReceiveRefundDto.setHousingFundType(HousingFundTypeEnum.FUNDTYPE_3.getNo());//认购金
					haveReceiveRefundDto.setBusinessFlag(BusinessFlagEnum.BUSINESSFLAG_7.getNo()); //认筹金转认购金(转入)
					haveReceiveRefundDto.setMerchantId(subscribe.getMerchantId());
					haveReceiveRefundDto.setUserCode(subscribe.getUserCode());
					haveReceiveRefundDto.setAccessCode(subscribe.getAccessCode());
					haveReceiveRefundDto.setCreateUserId(subscribe.getCreateUserId());
					haveReceiveRefundDto.setDelFlag("0");
					haveReceiveRefundDto.setDocType("0");
					haveReceiveRefundDto.setTransferStatus("0");
					haveReceiveRefundDto.setReChecked("0");
					haveReceiveRefundDto.setStatementType(Long.parseLong(StatementTypeEnum.TRANSFER.getNo()));
					HaveReceiveRefundDto resHave = getHaveReceiveRefundService().create(haveReceiveRefundDto);
					if(resHave == null){
		    			throw new Exception("认筹金转认购金（转入）新增失败！");
		    		}
				}		
			}
			
			/**
			 * 4.更改客户交易状态为认购，判断是否多套交易并更新状态 todo
			 * @param bugType 业务类型： 1 认筹、2 认购、3 签约
			 * @param busId 对应业务类型Id
			 * @param customerId 客户Id
			 * @param userId 用户Id
			 */
			getCustomerService().getCustomerEntity("2", Long.valueOf(id),subscribe.getCustomerId() , subscribe.getUpdateUserId());
			
			/**
			 * （认购审核通过）推送消息到app
			 * @author ny
			 * @param param noticeType 提醒类型, noticeBusinessId 业务主键Id
			 * @return 【${auditStatus}】房号：${roomName}；客户：${customer};
			 */
			NoticeEntity noticeEntity = new NoticeEntity();
			noticeEntity.setNoticeBusinessId(subscribe.getId());
			noticeEntity.setNoticeType("3");
			noticeEntity.setProcessInstanceId(processInstanceId);
			noticeEntity.setAudStatus("3");
			getSubscribeNoticeFacade().createSubscribeNotice(noticeEntity);

			/**
			 * 推送到渠道
			 */
			getChannelSendHttpMessageService().sendTransaction(subscribe.getId(), TransTypeEnum.SUBSCRIBE.getNo(), false);
		}else{
			/**
			 * 1.修改认筹记录审核状态为不通过
			 * 2.修改房源状态为未售或者认筹
			 */
			SubscribeDto updateDto = new SubscribeDto();
			updateDto.setId(subscribe.getId());
			updateDto.setAuditStatus(AuditStatusEnum.REJECT.getNo());
			updateDto.setCheckDate(new Date());
			subscribeService.update(updateDto);
			
			//房源状态为未售或者认筹
//			ProjectRoomDto projectRoomDto=new ProjectRoomDto();
//			projectRoomDto.setId(subscribe.getRoomId());
//			projectRoomDto.setRoomStatus(RoomStatusEnum.VENDIBILITY.getNo());
//			projectRoomService.update(projectRoomDto);
			
			//判断是否还有审核中或者审核通过的数据，以此来判断是否返回到可售
			PayDepositDto payDepositDto = new PayDepositDto();
			payDepositDto.setM_auditStatus(" and t.audit_status in (1,3)");
			payDepositDto.setRoomId(subscribe.getRoomId());
			List<PayDeposit> responseList = payDepositService.selectListByDto(payDepositDto);
			//房源状态为未售或者认筹
			if(responseList  == null || responseList.size() == 0){
				ProjectRoomDto projectRoomDto = new ProjectRoomDto();
				projectRoomDto.setId(subscribe.getRoomId());
				projectRoomDto.setRoomStatus(RoomStatusEnum.VENDIBILITY.getNo());//可售
				Integer responseRoomDto=projectRoomService.update(projectRoomDto);
				if(responseRoomDto < 1){
					throw new Exception("房间状态为可售出错");
				}
			}else{
				ProjectRoomDto projectRoomDto = new ProjectRoomDto();
				projectRoomDto.setId(subscribe.getRoomId());
				projectRoomDto.setRoomStatus(RoomStatusEnum.RESERVE.getNo());//认筹
				Integer responseRoomDto=projectRoomService.update(projectRoomDto);
				if(responseRoomDto < 1){
					throw new Exception("房间状态为认筹出错");
				}
			}
			
			/**
			 * （认购审核不通过）推送消息到app
			 * @author ny
			 * @param param noticeType 提醒类型, noticeBusinessId 业务主键Id
			 * @return 【${auditStatus}】房号：${roomName}；客户：${customer};
			 */
			NoticeEntity noticeEntity = new NoticeEntity();
			noticeEntity.setNoticeBusinessId(subscribe.getId());
			noticeEntity.setNoticeType("3");
			noticeEntity.setProcessInstanceId(processInstanceId);
			noticeEntity.setAudStatus("2");
			getSubscribeNoticeFacade().createSubscribeNotice(noticeEntity);
		}
	}
	
	private SubscribeNoticeFacade getSubscribeNoticeFacade(){
		return (SubscribeNoticeFacade)SpringWebContextUtil.getApplicationContext().getBean("subscribeNoticeFacade");
	}
	
	private ProjectRoomService getProjectRoomService(){
		return (ProjectRoomService)SpringWebContextUtil.getApplicationContext().getBean("projectRoomService");
	}
	
	private PayDepositService getPayDepositService(){
		return (PayDepositService)SpringWebContextUtil.getApplicationContext().getBean("payDepositService");
	}
	
	private SubscribeService getSubscribeService(){
		return (SubscribeService)SpringWebContextUtil.getApplicationContext().getBean("subscribeService");
	}
	
	private CustomerService getCustomerService(){
		return (CustomerService)SpringWebContextUtil.getApplicationContext().getBean("customerService");
	}
	
	private ActivitiProcessServiceImpl getActivitiProcessServiceImpl(){
		return (ActivitiProcessServiceImpl)SpringWebContextUtil.getApplicationContext().getBean("activitiProcessServiceImpl");
	}
	
	private RoomChangeHistoryService getRoomChangeHistoryService(){
		return (RoomChangeHistoryService)SpringWebContextUtil.getApplicationContext().getBean("roomChangeHistoryService");
	}
	
	private NeedReceiveRefundService getNeedReceiveRefundService(){
		return (NeedReceiveRefundService)SpringWebContextUtil.getApplicationContext().getBean("needReceiveRefundService");
	}
	
	private HaveReceiveRefundService getHaveReceiveRefundService(){
		return (HaveReceiveRefundService)SpringWebContextUtil.getApplicationContext().getBean("haveReceiveRefundService");
	}

	private ChannelSendHttpMessageService getChannelSendHttpMessageService(){
		return (ChannelSendHttpMessageService)SpringWebContextUtil.getApplicationContext().getBean("channelSendHttpMessageService");
	}

}
